package cn.iocoder.yudao.module.member.service.order;

import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.member.dal.mysql.activation.ActivationMapper;
import cn.iocoder.yudao.module.member.dal.mysql.activation.UserActivationMapper;
import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
import cn.iocoder.yudao.module.member.service.user.MemberUserService;
import cn.iocoder.yudao.module.pay.api.order.PayOrderApi;
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO;
import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;

import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import cn.iocoder.yudao.module.member.controller.admin.order.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.order.OrderDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.member.dal.mysql.order.ApiOrderMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;

/**
 * 订单 Service 实现类
 *
 * @author 家政
 */
@Service
@Validated
@Slf4j
public class OrderServiceImpl implements OrderService {
    @Resource
    private PayOrderApi payOrderApi;
    private static final String APP_KEY = "1";
    @Resource
    private ApiOrderMapper apiOrderMapper;
    @Resource
    private MemberUserMapper memberUserMapper;

    @Resource
    private MemberUserService memberUserService;
    @NotNull
    private OrderDO validateOrder(Long id) {
        // 校验订单是否存在
        OrderDO order = apiOrderMapper.selectById(id);
        if (order == null) {
            throw exception(ORDER_NOT_EXISTS);
        }
        return order;
    }
    @Override
    public void updateOrderPaid(Long id, Long payOrderId) {
// 1.1 校验订单是否存在
        OrderDO order = validateOrder(id);
        // 1.2 校验订单已支付
        if (order.getOrderStatus()!= 1) {
            // 特殊：如果订单已支付，且支付单号相同，直接返回，说明重复回调
            if (ObjectUtil.equals(order.getPayOrderId(), payOrderId)) {
                log.warn("[updateOrderPaid][order({}) 已支付，且支付单号相同({})，直接返回]", order, payOrderId);
                return;
            }
            log.error("[updateOrderPaid][order({}) 支付单不匹配({})，请进行处理！order 数据是：{}]",
                    id, payOrderId, JsonUtils.toJsonString(order));
            throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR);
        }

        // 2. 校验支付订单的合法性
        validatePayOrderPaid(order, payOrderId);

        // 3. 更新 Order 状态为已支付
        order.setOrderStatus(3);

        //开通会员
        MemberUserDO user = memberUserService.getUser(order.getUserId());
        //如果已经是会员则加时间，不是则加入会员
        if (user.getIsMember()){
            user.setMemberExpireDate(DateUtils.resultTime(order.getBeginTime(),order.getEndTime(),user.getMemberExpireDate()));
        } else {
            user.setIsMember(true);
            user.setMemberOpenDate(order.getBeginTime());
            user.setMemberExpireDate(order.getEndTime());
        }
        memberUserMapper.updateById(user);

        apiOrderMapper.updateById(order);
    }
    private PayOrderRespDTO validatePayOrderPaid(OrderDO order, Long payOrderId) {
        // 1. 校验支付单是否存在
        PayOrderRespDTO payOrder = payOrderApi.getOrder(payOrderId);
        if (payOrder == null) {
            log.error("[validatePayOrderPaid][order({}) payOrder({}) 不存在，请进行处理！]", order.getId(), payOrderId);
            throw exception(ORDER_NOT_FOUND);
        }

        // 2.1 校验支付单已支付
        if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) {
            log.error("[validatePayOrderPaid][order({}) payOrder({}) 未支付，请进行处理！payOrder 数据是：{}]",
                    order.getId(), payOrderId, JsonUtils.toJsonString(payOrder));
            throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS);
        }

        return payOrder;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createOrder(OrderSaveReqVO createReqVO) {
        createReqVO.setUserId(getLoginUserId());
        // 插入
        OrderDO order = BeanUtils.toBean(createReqVO, OrderDO.class);
        //订单的随机订单号
        String orderNo = generateOrderNo();
        order.setOrderSn(orderNo);
        order.setOrderStatus(1);
        apiOrderMapper.insert(order);
        // 创建支付订单
        //实际的支付金额 * 1000
        int money = createReqVO.getGoodsPrice().intValue();
        //支付过期时间 设置为15分钟
        String subject = "开通会员";
        LocalDateTime expireTime = LocalDateTime.now().plusMinutes(15);
        Long payOrderId = payOrderApi.createOrder(new PayOrderCreateReqDTO().setMerchantOrderId(String.valueOf(order.getId())).setAppKey(APP_KEY).setSubject(subject)
                .setBody(subject).setPrice(money).setExpireTime(expireTime).setUserIp(getClientIP()));
        //保存payOrderId 到 orderRecord
        order.setPayOrderId(payOrderId);
        apiOrderMapper.updateById(order);
        // 返回
        return payOrderId;
    }
    // 生成订单号：年月日 + 六位随机数
    public static String generateOrderNo() {
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();

        // 格式化为 YYYYMMDD
        String datePart = String.format("%04d%02d%02d",
                currentDate.getYear(),
                currentDate.getMonthValue(),
                currentDate.getDayOfMonth());

        // 生成六位随机数
        Random random = new Random();
        int randomNumber = random.nextInt(900000) + 100000; // 保证是6位数

        // 拼接订单号
        return datePart + randomNumber;
    }

    @Override
    public void updateOrder(OrderSaveReqVO updateReqVO) {
        // 校验存在
        validateOrderExists(updateReqVO.getId());
        // 更新
        OrderDO updateObj = BeanUtils.toBean(updateReqVO, OrderDO.class);
        apiOrderMapper.updateById(updateObj);
    }

    @Override
    public void deleteOrder(Long id) {
        // 校验存在
        validateOrderExists(id);
        // 删除
        apiOrderMapper.deleteById(id);
    }

    private void validateOrderExists(Long id) {
        if (apiOrderMapper.selectById(id) == null) {
            throw exception(ORDER_NOT_EXISTS);
        }
    }

    @Override
    public OrderDO getOrder(Long id) {
        return apiOrderMapper.selectById(id);
    }

    @Override
    public PageResult<OrderDO> getOrderPage(OrderPageReqVO pageReqVO) {
        return apiOrderMapper.selectPage(pageReqVO);
    }

}